package org.koon.web;

import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import org.koon.Dispatcher;
import org.koon.web.annotation.MethodApi;
import org.koon.web.annotation.TypeApi;
import org.ying.container.Container;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Router {

    private ClassLoader classLoader;
    private Map<String, Handler> directRouterMapping = new LinkedHashMap<>();
    private Container container;

    public Router(Container container) {
        this.container = container;
    }

    public Handler directLookup(String url){
        Handler handler = directRouterMapping.get(url);
        return handler;
    }

    public void createRouter(String... basePackages){
        Assert.notEmpty(basePackages);
        for (String basePackage : basePackages) {
            Set<Class<?>> classSet = ClassUtil.scanPackageByAnnotation(basePackage, TypeApi.class);
            classSet.forEach(clazz ->{
                TypeApi typeApi = AnnotationUtil.getAnnotation(clazz, TypeApi.class);
                String typePath = typeApi.path();
                if (StrUtil.isNotBlank(typePath)){
                    typePath = StrUtil.addPrefixIfNot(typePath,"/");
                    typePath =StrUtil.removeSuffix(typePath,"/");
                }
                String typePath_ = typePath;
                Object panda = container.getPanda(clazz);
                if (panda == null){
                    return;//
                }
                List<Method> methodList = ClassUtil.getPublicMethods(clazz, method -> {
                    MethodApi methodApi = AnnotationUtil.getAnnotation(method, MethodApi.class);
                    if (methodApi != null) {
                        return true;
                    }
                    return false;
                });
                methodList.forEach(method -> {
                    MethodApi methodApi = AnnotationUtil.getAnnotation(method, MethodApi.class);
                    String methodPath = methodApi.path();
                    if (StrUtil.isNotBlank(methodPath)){
                        methodPath = StrUtil.addPrefixIfNot(methodPath,"/");
                        methodPath =StrUtil.removeSuffix(methodPath,"/");
                    }
                    String api = typePath_ + methodPath;
                    if (StrUtil.isBlank(api)){
                        api = "/";
                    }
                    Handler handler = new Handler(panda,clazz,method,method.getParameters());
                    directRouterMapping.put(api,handler);
                });
            });
        }

    }

    public static void main(String[] args) {
        Method dispatch = ReflectUtil.getMethodByName(Dispatcher.class, "dispatch");
        Parameter[] parameters = dispatch.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter.getType());

        }
    }

}
